package jnpf.database.model.dbfield;

import jnpf.database.constant.DbAliasConst;
import jnpf.database.datatype.db.interfaces.DtInterface;
import jnpf.database.datatype.model.DataTypeModel;
import jnpf.database.datatype.model.ViewDtModel;
import jnpf.database.enums.DbAliasEnum;
import jnpf.database.model.dbfield.base.DbFieldModelBase;
import jnpf.database.model.dto.ModelDTO;
import jnpf.database.model.interfaces.JdbcGetMod;
import jnpf.database.source.DbBase;
import jnpf.exception.DataException;
import jnpf.util.StringUtil;
import lombok.Data;

import java.sql.ResultSet;

/**
 * 表字段模型
 *
 * @author JNPF开发平台组
 * @version V3.1.0
 * @copyright 引迈信息技术有限公司
 * @date 2021/3/12 15:31
 */
@Data
public class DbFieldModel extends DbFieldModelBase implements JdbcGetMod {

    private ViewDtModel viewDtModel;

    /**
     * 早期注释叫法
     */
    public String getFieldName(){
        return super.getComment();
    }

    /**
     * 数据类型格式化
     */
    public String formatDataTypeByView(String dbEncode) {
        if(this.viewDtModel == null){
            this.viewDtModel = new ViewDtModel(super.getDataType(), super.getLength(), dbEncode);
        }
        // 第一步：内置数据标准类型枚举为空直接返回 =======================
        if(this.viewDtModel.getDtEnum() == null){
            new DataException("目前还未支持" + dbEncode + "数据类型：" + getDataType()).printStackTrace();
            return super.getDataType();
        }
        // 第二步：获取可SQL执行数据类型模型 =======================
        DataTypeModel dataTypeModel;
        try{
            dataTypeModel = this.viewDtModel.getDtEnum().getDtLimit().convert(this.viewDtModel);
        }catch (Exception e){
            // 准备异常时，使用默认可执行数据类型
            this.viewDtModel.setIsFixed(true);
            dataTypeModel = this.viewDtModel.getDtEnum().getDtLimit().convert(this.viewDtModel);
        }
        return dataTypeModel.getDataType() + (StringUtil.isNotEmpty(dataTypeModel.getFormatLengthStr()) ? "(" + dataTypeModel.getFormatLengthStr() + ")" : "");
    }

    public void formatDataTypeLength(ViewDtModel viewDtModel, String dbEncode) {
        try {
            // ============== 字段数据类型长度 ===============
            // 数据内置数据标准类型枚举
            DtInterface dtEnum = viewDtModel.getDtEnumByDb(this.getDataType(), dbEncode);
            // 当dtEnum为空时
            if(dtEnum == null){
                this.setLength(viewDtModel.getViewCharLength().toString());
            }else {
                viewDtModel.setIsDbDataType(true);
                this.setLength(dtEnum.getDtLimit().convert(viewDtModel).getFormatLengthStr());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void setMod(ModelDTO modelDTO) {
        try{
            ResultSet result = modelDTO.getResultSet();
            DbBase dbBase = modelDTO.getDbBase();
            DbFieldModel model = new DbFieldModel();
            // 根据不同的库进行字段处理
            dbBase.setPartFieldModel(model, result);
            ViewDtModel viewDtModel = model.getViewDtModel();
            // ============== 字段数据类型 ===============
            this.setDataType(result.getString(DbAliasEnum.getAsByDb(dbBase, DbAliasConst.DATA_TYPE)));
            // ============== 字段类型、长度 ===============
            formatDataTypeLength(viewDtModel, dbBase.getJnpfDbEncode());
            // ============== 字段名 ===============
            this.setField(model.getField() != null ? model.getField() : result.getString(DbAliasEnum.getAsByDb(dbBase, DbAliasConst.FIELD)));
            // ============== 字段注释 ===============
            this.setComment(model.getComment() !=null ? model.getComment() : result.getString(DbAliasEnum.getAsByDb(dbBase, DbAliasConst.FIELD_COMMENT)));
            // ============== 字段主键 ==============
            this.setIsPrimaryKey(model.getIsPrimaryKey() != null ?  model.getIsPrimaryKey() : result.getInt(DbAliasEnum.PRIMARY_KEY.asByDb(dbBase)) == 1);
            // ============== 字段允空 ==============
            this.setNullSign(model.getNullSign() != null ? model.getNullSign() :
                    DbAliasEnum.ALLOW_NULL.getSign(result.getInt(DbAliasEnum.ALLOW_NULL.asByDb(dbBase))));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
